function $(elemId) {
	var elem = document.getElementById(elemId);
	if (elem == null) {
		var elems = document.getElementsByName(elemId);
		if (elems != null && elems.length > 0) {
			elem = elems[0];
		}
	}
    return elem;
}

function warn(msg) {
    window.alert(msg);
}

function getCursorPosition(e, elem) {
    var x, y;
    if (e.pageX || e.pageY) {
		x = e.pageX;
		y = e.pageY;
    } else {
		x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		y = e.clientY + document.body.scrollLTop + document.documentElement.scrollTop;
    }
    x -= elem.offsetLeft;
    y -= elem.offsetTop;
    return {x: x, y: y};
}

function GraphCode(canvasId, hiddenId) {
	var password;

	var CIRCLE_COUNT = 4;
	var CIRCLE_OFFSET = 60;
	var CIRCLE_RADIUS = 20;

	var circles = new Array(CIRCLE_COUNT * CIRCLE_COUNT);
    var drawArea = $(canvasId);
    var drawContext;
	var isMousePressed = false;
	var startPoint = null;
	
    {
		if (drawArea && drawArea.getContext) {
			drawContext = drawArea.getContext('2d');
		}
		
		if (drawContext == null) {
			warn("2D drawing context not supported.");
			return;
		}
		
		initEvents();
		clearCanvas();
    } // init

    function initEvents() {
		drawArea.addEventListener('mousemove', handleMouseMove, false);
		drawArea.addEventListener('mousedown', handleMouseDown, false);
		drawArea.addEventListener('mouseup', handleMouseUp, false);
		drawArea.addEventListener('mouseout', handleMouseUp, false);
    }	
	
	function clearCanvas() {
		startPoint = null;
		password = '';
		
		for (var i = 0; i < circles.length; i++) {
			circles[i] = {};
		}
		
		drawContext.clearRect(0, 0, drawArea.clientWidth, drawArea.clientHeight);
		buildCircles();
	}
	
    function handleMouseMove(e) {
		if (!isMousePressed) {
			return;
		}

		var cursorPos = getCursorPosition(e, drawArea);		
		drawLines(cursorPos.x, cursorPos.y);
    }
	
	function handleMouseDown() {
		isMousePressed = true;
	}
	
	function handleMouseUp() {
		isMousePressed = false;
		
		var hidden = $(hiddenId);
		if (hidden != null) {
			hidden.value = password;
		}
	}
     
    function buildCircles() {
		drawContext.lineWidth = 1;
		drawContext.strokeStyle = '#00f';
		
		var vx = 30;
		var count = 0;
		var pi = Math.PI * 2;
		for (var i = 0; i < CIRCLE_COUNT; i++) {
			var vy = 30;
			for (var j = 0; j < CIRCLE_COUNT; j++) {
				drawContext.beginPath();
				drawContext.arc(vx, vy, CIRCLE_RADIUS, 0, pi, true);
				drawContext.fill();
				drawContext.stroke();
				drawContext.closePath();
		
				circles[count++].center = {x: vx, y: vy};
				vy += CIRCLE_OFFSET;
			}
			vx += CIRCLE_OFFSET;
		}
    }
     
    function getCircle(x, y) {
		for (var i = 0; i < circles.length; i++) {
			if (isPointInCircle(x, y, circles[i].center)) {
				return i;
			}
		}
		return -1;
    }
     
    function isPointInCircle(x, y, center) {
		if (typeof center == 'undefined') {
			return false;
		}

		var distance = Math.sqrt((center.x - x) * (center.x - x) + (center.y - y) * (center.y - y));
		if (distance <= CIRCLE_RADIUS) {
			return true;
		} else {
			return false;
		}
    }
     
    function drawLines(x, y) {
		var index = getCircle(x, y);
		if (index < 0 || index >= circles.length) {
			return;
		}

		var circle = circles[index].center;
		var hasTwoPoints = true;
		if (startPoint == null) {
			startPoint = {x: circle.x, y: circle.y};
			hasTwoPoints = false;
		} else if (circle.x == startPoint.x && circle.y ==  startPoint.y) {
			return;
		}
		
		if (circles[index].selected != 1) {
			drawContext.beginPath();
			drawContext.lineWidth = 8;
			drawContext.strokeStyle = '#339900'; // blue
			drawContext.arc(circle.x, circle.y, CIRCLE_RADIUS, 0, Math.PI * 2, true);
			drawContext.fill();
			drawContext.stroke();
			drawContext.closePath();
			
			circles[index].selected = 1;
		}
		
		if (hasTwoPoints) {
			drawContext.beginPath();
			drawContext.lineWidth = 10;
			drawContext.strokeStyle = '#663300'; // blue			
			drawContext.moveTo(startPoint.x, startPoint.y);
			drawContext.lineTo(circle.x, circle.y);
			drawContext.fill();
			drawContext.stroke();
			drawContext.closePath();
		}

		startPoint = {x: circle.x, y: circle.y};
		password += index + ',';
    }
	
	this.clear = function() {
		clearCanvas();
	};
	
	this.getPassword = function() {
		return password;
	};
}

function User(mail, pwd, group) {
	var email = mail;
	var password = pwd;
	var groupId = group;
	
	this.setEmail = function(mail) {
		email = mail;
	};
	
	this.getEmail = function() {
		return email;
	};
	
	this.setPassword = function(pwd) {
		password = pwd;
	};
	
	this.getPassword = function() {
		return password;
	};
	
	this.setGroupId = function(grp) {
		groupId = grp;
	};
	
	this.getGroupId = function() {
		return groupId;
	};
	
}

function PasswordGroup() {
	var passwords = [
		'tyEsak_Auer_adT',
		'1j4h2l9_adFG0-t',
		'AK_09-yqaMa_rks',
	];
	
	this.getPassword = function(group) {	
		if (group < 1 || group > passwords.length) {
			warn('Invalid input');
			return;
		}
		
		return passwords[group - 1];
	};
	
	this.getDecodedPassword = function(pwd, groupId) {
		if (groupId == null || groupId < 1 || groupId > passwords.length) {
			return;
		}
		
		var pwdGrp = passwords[groupId - 1];
		if (pwdGrp == null) {
			return;
		} 
		
		var codes = pwd.split(',');
		if (codes == null || codes.length < 1) {
			warn('Password not entered!');
			return;
		}
		
		var password = '';
		for (var i = 0; i < codes.length; i++) {
			password += pwdGrp.charAt(parseInt(codes[i]));
		}
		return password;
	};
};

function Users() {
	var users = new Array();
	
	{
		users.push(new User('8210041@sina.com', 'tyE_kauerTdat', 1));
		users.push(new User('nanfchen@sina.com', '_AkrTda_', 2));
		users.push(new User('chennanfei@163.com', 'tkrTda_', 3));
	}
	
	this.getUser = function(email) {
		for (var i = 0; i < users.length; i++) {
			if (users[i].getEmail() == email) {
				return users[i];
			}
		}
		
		return null;
	};
};





